package com.youlu.campus.service.course;

import com.youlu.campus.entity.PayConfigPage;
import com.youlu.campus.entity.course.ActivityDeduction;
import com.youlu.campus.entity.course.UserActivityDeduction;
import com.youlu.campus.entity.course.vo.UserActivityDeductionVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import java.util.Date;

/**
 * @author : [dengbo]
 * @className : UserActivityDeductionService
 * @description : [限时扣减]
 * @createTime : [2023/3/21 15:08]
 */
@Service
@Slf4j
public class UserActivityDeductionService {

    @Autowired
    private MongoTemplate mongoTemplate;

    public UserActivityDeductionVo getUserDeductionVo(String userId, String activityId) {
        UserActivityDeductionVo vo = new UserActivityDeductionVo();
        ActivityDeduction activityDeduction = mongoTemplate.findOne(new Query(Criteria.where("activityId").is(activityId)), ActivityDeduction.class);
        if (activityDeduction == null) {
            log.info("activityId:{} deduction not exist", activityId);
            vo.setHasDeduction(false);
            vo.setActivityId(activityId);
            return vo;
        }
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(userId).and("activityId").is(activityId));
        UserActivityDeduction userActivityDeduction = mongoTemplate.findOne(query, UserActivityDeduction.class);
        if (userActivityDeduction != null) {
            log.info("activityId:{} deduction user:{} has receive", activityId, userId);
            vo.setHasDeduction(true);
            Long endTime = userActivityDeduction.getEndTime().getTime() - System.currentTimeMillis();
            vo.setDiffTime(endTime);
            vo.setMoney(activityDeduction.getMoney());
            vo.setActivityId(activityDeduction.getActivityId());
            return vo;
        }
        Date date = new Date();
        Update update = new Update();
        update.set("userId", userId);
        update.set("activityId", activityId);
        update.set("updatedTime", date);
        update.setOnInsert("receiveTime", date);
        Integer money = (activityDeduction.getMoney() == null || activityDeduction.getMoney() < 0) ? 0 : activityDeduction.getMoney();
        update.setOnInsert("money", money);
        Date endTime = new Date(System.currentTimeMillis() + activityDeduction.getTime() * 1000);
        update.setOnInsert("endTime", endTime);
        FindAndModifyOptions findAndModifyOptions = new FindAndModifyOptions();
        findAndModifyOptions.returnNew(Boolean.TRUE);
        findAndModifyOptions.upsert(Boolean.TRUE);
        UserActivityDeduction deduction = mongoTemplate.findAndModify(query, update, findAndModifyOptions, UserActivityDeduction.class);
        vo.setHasDeduction(true);
        vo.setDiffTime(deduction.getEndTime().getTime() - System.currentTimeMillis());
        vo.setMoney(money);
        vo.setActivityId(activityDeduction.getActivityId());
        return vo;
    }

    public UserActivityDeductionVo getUserDeductionVo(PayConfigPage payConfig, String userId, String code) {
        UserActivityDeductionVo vo = new UserActivityDeductionVo();
        vo.setHasDeduction(false);
        if (payConfig == null || payConfig.getDeductionMoney() == null || payConfig.getDeductionExpireTime() == null) {
            return vo;
        }
        if (payConfig.getDeductionMoney() <= 0 || payConfig.getDeductionExpireTime() <= 0) {
            return vo;
        }
        String activityId = payConfig.getActivityId();
        Query query = new Query(Criteria.where("userId").is(userId).and("activityId").is(activityId));
        if (StringUtils.isNotBlank(code)) {
            query.addCriteria(Criteria.where("opCode").is(code));
        }
        UserActivityDeduction userActivityDeduction = mongoTemplate.findOne(query, UserActivityDeduction.class);
        if (userActivityDeduction != null) {
            vo.setHasDeduction(true);
            Long endTime = userActivityDeduction.getEndTime().getTime() - System.currentTimeMillis();
            vo.setDiffTime(endTime);
            vo.setMoney(userActivityDeduction.getMoney());
            vo.setEndTime(userActivityDeduction.getEndTime());
            vo.setActivityId(activityId);
            return vo;
        }
        Date date = new Date();
        Update update = new Update();
        update.set("userId", userId);
        update.set("activityId", activityId);
        if (StringUtils.isNotBlank(code)) {
            update.set("opCode", code);
        }
        update.set("updatedTime", date);
        update.setOnInsert("receiveTime", date);
        update.setOnInsert("money", payConfig.getDeductionMoney());
        Date endTime = new Date(System.currentTimeMillis() + payConfig.getDeductionExpireTime() * 1000);
        update.setOnInsert("endTime", endTime);
        FindAndModifyOptions findAndModifyOptions = new FindAndModifyOptions();
        findAndModifyOptions.returnNew(Boolean.TRUE);
        findAndModifyOptions.upsert(Boolean.TRUE);
        UserActivityDeduction deduction = mongoTemplate.findAndModify(query, update, findAndModifyOptions, UserActivityDeduction.class);
        vo.setHasDeduction(true);
        vo.setDiffTime(deduction.getEndTime().getTime() - System.currentTimeMillis());
        vo.setMoney(deduction.getMoney());
        vo.setActivityId(activityId);
        vo.setEndTime(endTime);
        return vo;
    }

}
